package com.tedu.ds.order.service.impl;

import com.tedu.ds.base.enmu.OrderPayStatus;
import com.tedu.ds.base.enmu.OrderStatus;
import com.tedu.ds.customer.mapper.CustomerMapper;
import com.tedu.ds.customer.pojo.dto.CustomerQuery;
import com.tedu.ds.customer.pojo.vo.CustomerVO;
import com.tedu.ds.employee.mapper.EmployeeMapper;
import com.tedu.ds.employee.pojo.dto.EmployeeQuery;
import com.tedu.ds.employee.pojo.vo.EmployeeVO;
import com.tedu.ds.order.mapper.OrderMapper;
import com.tedu.ds.order.pojo.dto.OrderQuery;
import com.tedu.ds.order.pojo.dto.OrderSaveParam;
import com.tedu.ds.order.pojo.entity.Order;
import com.tedu.ds.order.pojo.vo.OrderVO;
import com.tedu.ds.order.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class OrderServiceImpl implements OrderService {
    @Autowired
    OrderMapper orderMapper;

    @Scheduled(cron = "0 * * * * ?")
    @Transactional
    public void cleanupUnpaidOrders(){
        Instant now=Instant.now();
        // 定义日期格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
                .withZone(ZoneId.systemDefault());
        // 将Instant格式化为字符串
        String formattedDate = formatter.format(now);
        OrderQuery orderQuery=new OrderQuery();
        orderQuery.setPayStatus(OrderPayStatus.UNPAID.getCode());
        orderQuery.setCreateTime(formattedDate);
        List<OrderVO> orderVOS = orderMapper.selectByPayStatusANDCreateTime(orderQuery);
        if (!orderVOS.isEmpty()){
            for (OrderVO o:orderVOS){
                Order order=new Order();
                BeanUtils.copyProperties(o,order);
                order.setStatus(OrderStatus.CANCELLED.getCode());
                order.setEndTime(new Date());
                orderMapper.update(order);
                log.info("订单：{}号未支付，状态更新为已取消",o.getId());
            }
        }
    }

    @Override
    public void save(OrderSaveParam orderSaveParam) {
        Order order = new Order();
        BeanUtils.copyProperties(orderSaveParam,order);
        if(order.getId()==null){
            order.setPayStatus(OrderPayStatus.UNPAID.getCode());
            orderMapper.insert(order);
        }else{
            if(order.getEmpId()!=null){
                if (order.getStatus().equals("20")){
                    order.setStartTime(new Date());
                }
                if (order.getStatus().equals("30")){
                    order.setEndTime(new Date());
                }
            }
            orderMapper.update(order);
        }

    }


    @Override
    public void deleteById(Long id) {
        orderMapper.deleteById(id);
    }

    @Autowired
    private EmployeeMapper employeeMapper;
    @Autowired
    private CustomerMapper customerMapper;

    @Override
    public List<OrderVO> select(OrderQuery orderQuery) {
        List<OrderVO> list=orderMapper.select(orderQuery);
        if (list.size()>0){
            for (OrderVO orderVO:list){
                CustomerQuery customerQuery = new CustomerQuery();
                customerQuery.setId(orderVO.getCustId());
                List<CustomerVO> customerVOList = customerMapper.select(customerQuery);
                if (customerVOList.size()>0){
                    orderVO.setCustName(customerVOList.get(0).getUsername());
                }else {
                    orderVO.setCustName("不存在");
                }
                EmployeeQuery employeeQuery = new EmployeeQuery();
                employeeQuery.setId(orderVO.getEmpId());
                List<EmployeeVO> employeeVOList = employeeMapper.select(employeeQuery);
                if (employeeVOList.size()>0){
                    orderVO.setEmpName(employeeVOList.get(0).getUsername());
                }else {
                    orderVO.setEmpName("不存在");
                }
            }
        }
        return list;
    }

    @Autowired
    private RedissonClient redissonClient;

    private static final String LOCK_PREFIX = "order:update:lock:";
    @Override
    @Transactional
    public void updateStatus(OrderSaveParam orderSaveParam) {
        // 构建锁的唯一标识，通常基于订单ID
        String lockKey = LOCK_PREFIX + orderSaveParam.getId();

        // 获取锁对象
        RLock lock = redissonClient.getLock(lockKey);

        try {
            // 尝试获取锁，最多等待10秒，持有时间为30秒
            if (lock.tryLock(10, 30, TimeUnit.SECONDS)) {
                try {
                    // 执行更新操作
                    Order order = new Order();
                    BeanUtils.copyProperties(orderSaveParam, order);
                    if(order.getEmpId()!=null){
                        if (order.getStatus().equals("20")){
                            order.setStartTime(new Date());
                        }
                    }
                    orderMapper.updateStatus(order);
                } finally {
                    // 确保在任何情况下都释放锁
                    lock.unlock();
                }
            } else {
                // 如果未能获取锁，可以抛出异常或者采取其他措施
                throw new RuntimeException("Failed to acquire lock for order ID: " + orderSaveParam.getId());
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt(); // 恢复中断状态
            throw new RuntimeException("Interrupted while trying to acquire lock", e);
        }
    }

}
